<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/welcome' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>数据统计</el-breadcrumb-item>
      <el-breadcrumb-item>数据报表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片视图 -->
    <el-card class="box-card">
      <div id="main"></div>
    </el-card>
  </div>
</template>

<script>
// 1、导入echarts
import * as echarts from 'echarts'
export default {
  data() {
    return {
      // 需要合并的数据
      options: {
        title: {
          text: '用户来源'
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross',
            label: {
              backgroundColor: '#E9EEF3'
            }
          }
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: [
          {
            boundaryGap: false
          }
        ],
        yAxis: [
          {
            type: 'value'
          }
        ]
      }
    }
  },
  async mounted() {
    // 基于准备好的dom，初始化echarts实例
    var myChart = echarts.init(document.getElementById('main'))
    const { data: res } = await this.$http.get('reports/type/1')
    if (res.meta.status !== 200) {
      return this.$message.error('获取报表数据失败')
    }
    // 绘制图表
    // const newoptions = Object.assign({}, this.options, res.data)
    const newoptions = this.assignDeep({}, this.options, res.data)
    myChart.setOption(newoptions)
  },
  methods: {
    assignDeep(target, ...sources) {
      // 1. 参数校验
      if (target == null) {
        throw new TypeError('Cannot convert undefined or null to object')
      }
      // 2. 如果是基本类型，则转换包装对象
      const result = Object(target)
      // 3. 缓存已拷贝过的对象
      const hash = new WeakMap()
      // 4. 目标属性是否可直接覆盖赋值判断
      function canPropertyCover(node) {
        if (!node.target[node.key]) {
          return true
        }
        if (node.target[node.key] == null) {
          return true
        }
        if (!(typeof node.target[node.key] === 'object')) {
          return true
        }
        if (Array.isArray(node.target[node.key]) !== Array.isArray(node.data)) {
          return true
        }
        return false
      }
      sources.forEach((v) => {
        const source = Object(v)
        const stack = [
          {
            data: source,
            key: undefined,
            target: result
          }
        ]
        while (stack.length > 0) {
          const node = stack.pop()
          if (typeof node.data === 'object' && node.data !== null) {
            let isPropertyDone = false
            if (hash.get(node.data) && node.key !== undefined) {
              if (canPropertyCover(node)) {
                node.target[node.key] = hash.get(node.data)
                isPropertyDone = true
              }
            }

            if (!isPropertyDone) {
              let target
              if (node.key !== undefined) {
                if (canPropertyCover(node)) {
                  target = Array.isArray(node.data) ? [] : {}
                  hash.set(node.data, target)
                  node.target[node.key] = target
                } else {
                  target = node.target[node.key]
                }
              } else {
                target = node.target
              }

              Reflect.ownKeys(node.data).forEach((key) => {
                // 过滤不可枚举属性
                if (
                  !Object.getOwnPropertyDescriptor(node.data, key).enumerable
                ) {
                  return
                }
                stack.push({
                  data: node.data[key],
                  key: key,
                  target: target
                })
              })
            }
          } else {
            Object.assign(node.target, { [node.key]: node.data })
          }
        }
      })

      return result
    }
  }
}
</script>

<style lang="less" scoped>
#main {
  width: 750px;
  height: 400px;
}
</style>
